package com.es.disped.web.controller.login;

import java.util.List;
import java.util.Map;
import java.util.Optional;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.es.disped.api.sms.SmsService;
import com.es.disped.api.user.UserService;
import com.es.disped.common.constant.RecordStatus;
import com.es.disped.common.model.MsgModel;
import com.es.disped.core.annotation.LogInject;
import com.es.disped.core.controller.BaseController;
import com.es.disped.dao.model.LoginUser;
import com.es.disped.dao.model.User;
import com.es.disped.dao.model.UserExample;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;

@Api("用户登录注册接口")
@Controller
@RequestMapping("/common/login")
public class LoginController extends BaseController{
	
	@LogInject
	Logger log;
	@Autowired
	SmsService smsService;
	@Autowired
	UserService userService;
	@Autowired
	RedisTemplate<String, String> redisTemplate;
    
    
    @ApiOperation(value="验证手机号",httpMethod="POST",response=MsgModel.class,notes="检查手机号是否被注册")
    @ApiImplicitParam(name="phone",value="手机号",required=true,dataType="String")
    @RequestMapping(value="/check/phone",method=RequestMethod.POST)
    public @ResponseBody MsgModel checkPhone(@RequestBody Map<String, Object> paramMap)
    {
    	UserExample userExample=new UserExample();
    	userExample.createCriteria().andPhoneEqualTo(paramMap.get("phone").toString());
    	List<User> users=userService.selectByExample(userExample);
    	return new MsgModel(this.isNull(users)?HttpStatus.OK.value():HttpStatus.NOT_ACCEPTABLE.value(),
    			this.isNull(users)?"":"手机号已被注册");
    }
    

    
    @ApiOperation(value="注册",httpMethod="POST",response=MsgModel.class,notes="实现用户信息注册（个人注册）")
	@RequestMapping(value="/registe", method=RequestMethod.POST)
	public @ResponseBody MsgModel registe(@RequestBody @ApiParam(name="user", value="用户对象",required=true) User user)
	{
		int count=0;
		if(Optional.of(user)
		.filter((username)->user.getUsername()!=null)
		.filter((phone)->user.getPhone()!=null)
		.filter((password)->user.getPassword()!=null)
		.isPresent()
		&&redisTemplate.hasKey(user.getPhone()))//防止用户替换手机号
		{
			user.setUserId(getUUID());
			user.setPassword(this.md5(user.getPassword()));
			user.setJoinDate(this.currentDate("yyyy-MM-dd HH:mm:ss"));
			user.setUserValid(RecordStatus.VERTIFY.getValue());
			count=userService.insert(user);
		}
		//无论注册是否成功，删除验证码
		redisTemplate.delete(user.getPhone());
		//无论是否成功，保存用户ID
		this.getSession().setAttribute("registeUser", user);
		log.debug(count==1?HttpStatus.OK.value()+"-注册成功":HttpStatus.EXPECTATION_FAILED.value()+"-注册失败",user);
		return new MsgModel(count==1?HttpStatus.OK.value():HttpStatus.EXPECTATION_FAILED.value(),count==1?"注册成功":"注册失败");
	}


	@ApiOperation(value="登录",httpMethod="POST", response=MsgModel.class,notes="根据用户名密码实现用户登录")
	@ApiImplicitParam(name="paramMap",value="登录",required=true,dataType="HashMap")
	@RequestMapping(value="/sign/in", method=RequestMethod.POST)
	public @ResponseBody MsgModel login(@RequestBody Map<String, Object> paramMap)
	{
		paramMap.put("password", this.md5(paramMap.get("password").toString()));
        LoginUser loginUser = this.getService().selectOne(
        		"com.es.disped.dao.mapper.login.LoginCustomMapper.getLoginUser",
        		paramMap.get("phone").toString());
        if (this.isNull(loginUser))
        {
        	return new MsgModel(HttpStatus.FORBIDDEN.value(), "用户名、密码不正确！");
        }

        if (RecordStatus.USEAGE.getValue()!=loginUser.getUserValid())
        {
        	return new MsgModel(HttpStatus.FORBIDDEN.value(), "该用户"+RecordStatus.getName(loginUser.getUserValid()));
        }
        try 
        {
            Subject subject = SecurityUtils.getSubject();
            // 当前用户是否已通过身份验证
            if (!subject.isAuthenticated()) 
            {
            	
                UsernamePasswordToken token = new UsernamePasswordToken(paramMap.get("phone").toString(),
                														paramMap.get("password").toString());
                
                token.setRememberMe(Boolean.valueOf(paramMap.get("remember").toString()));
                //验证角色和权限
                subject.login(token);
                this.getSession().setAttribute(this.sessionUser, loginUser);
            }
            return new MsgModel(HttpStatus.OK.value(), paramMap.get("remember").toString(),loginUser);
        } catch (AuthenticationException e) {
            e.printStackTrace();
            return new MsgModel(HttpStatus.EXPECTATION_FAILED.value(), "登录认证失败");
        }
	}
	
	
	
	@ApiOperation(value="退出登录",httpMethod="GET",response=MsgModel.class,notes="退出登录")
	@RequestMapping(value="/sign/out",method=RequestMethod.GET)
	public @ResponseBody MsgModel logout()
	{
		 Subject subject = SecurityUtils.getSubject();
		 LoginUser loginUser=(LoginUser) subject.getPrincipal();
		 System.out.println(">>>>>>>>>>>logout>>>>>>>>>>>"+loginUser);
		 if(subject.isAuthenticated())
		 {
			 subject.logout();
			 this.getSession().invalidate();
		 }
		return new MsgModel(HttpStatus.OK.value(), "退出");
	}
}
